home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Fixation 1.3 / main.c < prev    next >
Text File  |  1996-04-14  |  13KB  |  571 lines

  1. /*****
  2.  * main.c for fixation © 1996 Adam Miller
  3.      for more info see http://zoo.cs.yale.edu:8000/~miller/comp/fix.html
  4.      
  5.  compiled in Metrowerks Codewarrior (! yeah !) 1.2.2
  6.  
  7.  *
  8.  *
  9.  *****/
  10.  
  11. #define ICC 0
  12.  
  13. #include <string.h>
  14. #include <profiler.h>
  15.  
  16. #include "mytypes.h"
  17. #include "ResRefs.h"
  18. #include "error.h"
  19.  
  20. #include "menus.h"
  21. #include "window.h"
  22. #include "main.h"
  23. #include "util.h"
  24. #include "incoming.h"
  25. #include "preffile.h"
  26. #include "connexions.h"
  27. #include "game.h"
  28. #include "globals.h"
  29.  
  30. #include "tcpstuff.h"
  31.  
  32. // some globals 'n shit
  33.  
  34. enum {
  35.     kCurPrefVersion = 1
  36. };
  37.  
  38. int timeToQuit = false;
  39. int gInBackground = false;
  40. Shortcut *gShortcuts;
  41.  
  42. extern    Rect        dragRect;
  43.  
  44. void InitMacintosh(void);
  45. void HandleMouseDown (EventRecord    *theEvent);
  46. void HandleEvent(void);
  47. void Bolo(void);
  48.  
  49. static char *
  50. RandomName(void)
  51. {
  52.     short rnd = Random() % 8;
  53.     if (rnd < 0) rnd *= -1;
  54.     
  55.     switch (rnd) {
  56.         case 0: return "Tessai";
  57.         case 1: return "Benisato";
  58.         case 2: return "Mushizo";
  59.         case 3: return "Utsutso";
  60.         case 4: return "Shujima";
  61.         case 5: return "Yurimaru";
  62.         case 6: return "Zakuru";
  63.         default: return "Genma";
  64.     }
  65. }
  66.  
  67. static void
  68. InitializePrefValues(void)
  69. {
  70.     gPrefs.versionNumber = kCurPrefVersion;
  71.     strcpy(gPrefs.name, RandomName());
  72. #if ICC
  73.     strcpy(gPrefs.serverAddress, "chess.lm.com");
  74.     gPrefs.serverType = kIcc;
  75.     strcpy(gPrefs.name, "guest");        // how boring
  76.     gPrefs.timeseal = true;
  77. #else
  78.     strcpy(gPrefs.serverAddress, "ics.onenet.net");
  79.     gPrefs.serverType = kFics;
  80.     gPrefs.timeseal = true;
  81. #endif
  82.     SetRect(&gPrefs.textWindPos, 0, 0, 0, 0);
  83.     SetRect(&gPrefs.gameWindPos1, 0, 0, 0, 0);
  84.     gPrefs.useSound = true;
  85.     gPrefs.port = 5000;
  86.     gPrefs.password[0] = 0;
  87.     gPrefs.numLogins = 0;
  88.     gPrefs.saidHi = false;
  89.     gPrefs.smartClose = true;
  90.     gPrefs.autoFlag = false;
  91.     gPrefs.autoBug = true;
  92.     gPrefs.autoFlip = true;
  93.     gPrefs.adminColors = false; gPrefs.channelColors = true;
  94.     gPrefs.smartText = true;
  95.     gPrefs.slowText = false;
  96.     gPrefs.minimal = false;
  97.     gPrefs.colWhite.red = 0xE000; gPrefs.colWhite.green = 0xE000; gPrefs.colWhite.blue = 0xE000;
  98.     gPrefs.colBlack.red = 22318; gPrefs.colBlack.green = 36864; gPrefs.colBlack.blue = 34744;
  99.     gPrefs.trueColors = true;
  100.     gPrefs.pieceSet = 0;
  101.     gPrefs.currentSize = 9;
  102.     GetFNum("\pMonaco", &gPrefs.currentFont);        /* Initial font should be monaco     */
  103.     gPrefs.boardSize1 = 32 * 8;
  104.     gPrefs.boardSize2 = 32 * 8;
  105.     gPrefs.backgroundOnDrag = false;
  106.     gPrefs.soundTells = true;
  107. }
  108.  
  109. static void
  110. GetPrefs(void)
  111. {
  112.     int i;
  113.     Boolean prefsValid = false;
  114.     
  115. //    if (!prefsValid)
  116.         InitializePrefValues();
  117.     
  118.         // try to read the prefs in from the file
  119.     if (DoReadPrefs((Ptr) &gPrefs, sizeof(prefStruct), "\pFixation Prefs") == sizeof(prefStruct)) {
  120.             // check the version of the saved prefs is adequate
  121.         prefsValid = true;
  122. //        if (gPrefs.versionNumber < kCurPrefVersion)
  123. //            prefsValid = false;
  124.     }
  125.     
  126.     gPrefs.numLogins++;
  127.     
  128.     
  129.         // now read shortcuts
  130.     gShortcuts = (Shortcut *) NewPtr(sizeof(Shortcut) * kShortcuts); verify(gShortcuts);
  131.     for (i=0;i<kShortcuts;i++)
  132.         gShortcuts[i].jexiste = false;
  133.     if (DoReadPrefs((Ptr) gShortcuts, sizeof(Shortcut) * kShortcuts,
  134.             "\pFixation Shortcuts") == 0) {
  135.             // make some initial shortcuts
  136.         Shortcut *sc = gShortcuts;
  137. #if !(ICC)
  138.         strcpy(sc->shortcut, "Generic FICS");
  139.         strcpy(sc->serverAddress, "ics.onenet.net");
  140.         sc->name[0] = 0; sc->password[0] = 0; sc->port = 5000; sc->serverType = kFics;
  141.         sc->timeseal = false; sc->jexiste = true;
  142.  
  143.         sc = &gShortcuts[1];
  144. #else
  145.         sc = &gShortcuts[0];
  146. #endif
  147.         strcpy(sc->shortcut, "Generic ICC");
  148.         strcpy(sc->serverAddress, "chess.lm.com");
  149.         sc->name[0] = 0; sc->password[0] = 0; sc->port = 5000; sc->serverType = kIcc;
  150.         sc->timeseal = true; sc->jexiste = true;
  151.     }
  152. }
  153.  
  154. void InitMacintosh(void)
  155. {
  156.     MaxApplZone();
  157.     
  158.     InitGraf(&qd.thePort);
  159.     InitFonts();
  160.     FlushEvents(everyEvent, 0);
  161.     InitWindows();
  162.     InitMenus();
  163.     TEInit();
  164.     InitDialogs(0L);
  165.     InitCursor();
  166.     GetDateTime((ulong *) &qd.randSeed);
  167.     
  168.     MyInitUtil();
  169.     
  170. //    if (DoReadPrefs((Ptr) &prefs, sizeof(preftype)) == sizeof(preftype)) {
  171. //    }
  172. //    prefs.shouldpatchbutt = true;
  173. }
  174.  
  175. void Adjust_text( void )
  176. {
  177.     short oldScroll, newScroll, delta;
  178.     
  179.     oldScroll = (**myText).viewRect.top - (**myText).destRect.top;
  180.     newScroll = GetCtlValue(gVBar) * GetLineHeight(myText);
  181.     delta = oldScroll - newScroll;
  182.     if (delta != 0)
  183.         TEScroll(0, delta, myText);
  184. }
  185.  
  186. /*
  187. static void Adjust_text( void )
  188. {
  189.     short    scroll_down;
  190.     short            old_scroll;
  191.     Rect            update_rect;
  192.     ControlHandle    the_bar = gVBar;
  193.     
  194.     old_scroll = (**myText).viewRect.top - (**myText).destRect.top;
  195.     scroll_down = old_scroll - GetCtlValue( the_bar );
  196.     if (scroll_down == 0)
  197.         return;
  198.     TEScroll( 0, scroll_down, myText );
  199. }
  200. */
  201.  
  202. static pascal void Scroll_text( ControlHandle the_bar, int part_code )
  203. {
  204.     short offset;
  205.     
  206.     switch (part_code) {
  207.         case inUpButton: 
  208.             offset = -1; break;
  209.         case inDownButton: 
  210.             offset = 1; break;
  211.         case inPageUp: 
  212.             offset = -10; break;
  213.         case inPageDown: 
  214.             offset = 10; break;
  215.         default:
  216.             offset = 0;
  217.     }
  218.     
  219.     SetCtlValue(the_bar, GetCtlValue(the_bar) + offset);
  220.     Adjust_text();
  221. }
  222.  
  223.  
  224.  
  225. /* ---------------------- Handle_scroll ---------------------------- */
  226. /*
  227.     Called by Help_filter to handle mouseDown events in the scroll bar.
  228. */
  229. static void Handle_scroll( WindowPtr dialog, short the_part, Point where )
  230. {
  231.     ControlHandle the_bar;
  232.     ControlActionUPP myupp = NewControlActionProc(Scroll_text);
  233.     
  234.     SetPort( myWindow );
  235.     the_bar = gVBar;
  236.     if (the_part == inThumb)
  237.     {
  238.         (void) TrackControl( the_bar, where, nil );
  239.         Adjust_text( );
  240.     }
  241.     else
  242.         (void) TrackControl( the_bar, where, myupp );
  243.     
  244. }
  245.  
  246.  
  247. void HandleMouseDown (EventRecord    *theEvent)
  248. {
  249.     WindowPtr    theWindow;
  250.     int            windowCode = FindWindow (theEvent->where, &theWindow);
  251.     short    the_part;
  252.     ControlHandle    the_control;
  253.     
  254.     switch (windowCode)
  255.       {
  256.       case inSysWindow: 
  257.         SystemClick (theEvent, theWindow);
  258.         break;
  259.         
  260.       case inMenuBar:
  261.           AdjustMenus();
  262.         HandleMenu(MenuSelect(theEvent->where));
  263.         break;
  264.         
  265.       case inDrag:
  266.         DragWindow(theWindow, theEvent->where, &dragRect);
  267.     /*    if (theWindow == (WindowPtr) gameWindow) {
  268.             Point pt = {0, 0};
  269.             SetPort((WindowPtr) gameWindow);
  270.             LocalToGlobal(&pt);
  271.                 // make sure window aligned to 4 pixels
  272.             if (pt.h & 3) {    // it's not
  273.                 pt.h -= pt.h & 3;
  274.                 MoveWindow((WindowPtr) gameWindow, pt.h, pt.v, false);
  275.             }
  276.         }*/
  277.         break;
  278.             
  279.       case inContent:
  280.         if (theWindow != FrontWindow()) {
  281.             SelectWindow(theWindow);
  282.             if (theWindow == myWindow)
  283.                 DrawGrowIcon(myWindow);
  284.         }
  285.         else if (theWindow == myWindow) {
  286.             Point pt = theEvent->where;
  287.             SetPort(myWindow);
  288.             GlobalToLocal(&pt);
  289.             the_part = FindControl( pt, theWindow, &the_control );
  290.             
  291.             if (the_part && ((**the_control).contrlMax > 1) )
  292.                 Handle_scroll( myWindow, the_part, pt );    
  293.             else if (PtInRect( pt, &(**myText).viewRect ))
  294.                 TEClick(pt, false, myText);
  295.             else if (PtInRect( pt, &(**typeText).viewRect ))
  296.                 TEClick(pt, false, typeText);
  297.         }
  298.         else {
  299.             Point pt = theEvent->where;
  300.             SetPort(FrontWindow());
  301.             GlobalToLocal(&pt);
  302.             HandleGameClick(&pt);
  303.         }
  304.         break;
  305.           
  306.     case inGrow:
  307.         if (theWindow == myWindow)
  308.             GrowTextWindow(theEvent->where);
  309.         else
  310.             GrowGameWindow((CWindowPtr) theWindow, theEvent->where);
  311.         break;
  312.           
  313.       case inGoAway:
  314.           if (TrackGoAway(theWindow, theEvent->where))
  315.             if (theWindow == myWindow)
  316.                 HideWindow(myWindow);
  317.             else
  318.                 CloseGameWindow(theWindow);
  319.         break;
  320.  
  321.         case inZoomIn: case inZoomOut:
  322.             ZoomWindow(theWindow, windowCode, true);
  323.             break;
  324.             
  325.         default: break;
  326.       }
  327. }
  328. /* end HandleMouseDown */
  329.  
  330.  
  331. /****
  332.  * HandleEvent()
  333.  *
  334.  *        The main event dispatcher. This routine should be called
  335.  *        repeatedly (it  handles only one event).
  336.  *
  337.  *****/
  338.  
  339. extern short gClickType;
  340.  
  341. void HandleEvent(void)
  342. {
  343.     WindowPtr    theWindow;
  344.     short            ok;
  345.     short item;
  346.     EventRecord    theEvent;
  347.     DialogPtr dp;
  348.     char c;
  349.  
  350. //    HiliteMenu(0);
  351. //    SystemTask();        /* Handle desk accessories */
  352.     
  353.     if (gPrefs.backgroundOnDrag || (gClickType == 0))
  354.         ok = WaitNextEvent(everyEvent, &theEvent, 5, nil);
  355.     else
  356.         ok = GetOSEvent(everyEvent, &theEvent);
  357.  
  358. /*    if (ok)        // don't need to call regardless, no editable text
  359.             // we only call with mousedown to avoid destruction of updates
  360.             // if we had stuff there besides buttons, shit would hit the fan
  361.         if (theEvent.what == mouseDown && IsDialogEvent(&theEvent))
  362.             if (DialogSelect(&theEvent, &dp, &item))
  363.                 if (dp == (DialogPtr) itemWindow)
  364.                     ItemWindowButton(item);
  365. */
  366.  
  367. //    ok = GetNextEvent (everyEvent, &theEvent);
  368.     if (ok)
  369.       switch (theEvent.what)
  370.         {
  371.         case mouseDown:
  372.             HandleMouseDown(&theEvent);
  373.             break;
  374.             
  375.         case keyDown: 
  376.         case autoKey:
  377.             if ((theEvent.modifiers & cmdKey) != 0)
  378.               {
  379.               AdjustMenus();
  380.               HandleMenu(MenuKey((char) (theEvent.message & charCodeMask)));
  381.               }
  382.             else // if (FrontWindow() == myWindow)
  383.             {
  384.                 c = (char) (theEvent.message & charCodeMask);
  385.                 if (c == '\r' || c == '\n')
  386.                     EnteredText();        // they finished what they were saying
  387.                 else if (c == 11) {        // page up
  388.                     SetCtlValue(gVBar, GetCtlValue(gVBar) - gLinesInText + 2);
  389.                     Adjust_text();
  390.                 }
  391.                 else if (c == 12) {        // page down
  392.                     SetCtlValue(gVBar, GetCtlValue(gVBar) + gLinesInText - 2);
  393.                     Adjust_text();
  394.                 }
  395.                 else if (c == 5) {        // help (up one line)
  396.                     SetCtlValue(gVBar, GetCtlValue(gVBar) - 1);
  397.                     Adjust_text();
  398.                 }
  399.                 else if (c == 127) {        // del (down one line)
  400.                     SetCtlValue(gVBar, GetCtlValue(gVBar) + 1);
  401.                     Adjust_text();
  402.                 }
  403.                 else if (c == 1) {        // home
  404.                     SetCtlValue(gVBar, 0);
  405.                     Adjust_text();
  406.                 }
  407.                 else if (c == 4) {        // end
  408.                     SetCtlValue(gVBar, GetCtlMax(gVBar));
  409.                     Adjust_text();
  410.                 }
  411.                 else {
  412.                     //TEKey(c, typeText);
  413.                     //tprintf("%d ", c);
  414.                     HandleKey(c);
  415.                 }
  416.             }
  417.             break;
  418.             
  419.         case updateEvt:
  420.             theWindow = (WindowPtr) theEvent.message;
  421.             BeginUpdate(theWindow);
  422.             SetPort(theWindow);
  423.             if (theWindow == myWindow)
  424.                 DrawTextWindow();
  425.             else
  426.                 DrawGameWindow(theWindow);
  427.             EndUpdate(theWindow);
  428.             break;
  429.  
  430.         case osEvt:
  431.             switch ((theEvent.message >> 24) & 0x0FF) {        /* high byte of message */
  432.                 case suspendResumeMessage:        /* suspend/resume is also an activate/deactivate */
  433.                     gInBackground = (theEvent.message & resumeFlag) == 0;
  434.                     if (!gInBackground) {
  435.                         InitCursor();
  436.                         TEFromScrap();
  437.                     }
  438.                     break;
  439.             }
  440.             break;
  441.             
  442.         case activateEvt:
  443.         //    SetPort(myWindow);
  444.         //    InvalRect(&myWindow->portRect);
  445.             InitCursor();
  446.             TEFromScrap();
  447.             break;
  448.             
  449.         default: break;
  450.         }
  451. }
  452. /* end HandleEvent */
  453.  
  454.  
  455. Rect
  456. GetWindowRect(WindowPtr win)
  457. {
  458.     Point pt = {0, 0};
  459.     Rect r;
  460.  
  461.     SetPort(win);
  462.     LocalToGlobal(&pt);
  463.     r = win->portRect;
  464.     OffsetRect(&r, pt.h, pt.v);
  465.     
  466.     return r;
  467. }
  468.  
  469. static void
  470. PreparePrefs(void)
  471. {
  472.     short nnn;
  473.     
  474.     gPrefs.textWindPos = GetWindowRect(myWindow);
  475. }
  476.  
  477. void Terminate(void);
  478. void Terminate(void)
  479. {
  480.     ReleaseStreams();
  481.     ExitToShell();
  482. }
  483.  
  484. static void
  485. ExitStuff(void)
  486. {
  487.     if (gPlaying)
  488.         StopPlaying();
  489.     PreparePrefs();
  490.     DoSavePrefs((Ptr) &gPrefs, sizeof(prefStruct), "\pFixation Prefs");
  491.     DoSavePrefs((Ptr) gShortcuts, sizeof(Shortcut) * kShortcuts,
  492.             "\pFixation Shortcuts");
  493. }
  494.  
  495. static void
  496. BuffersToScreen(void)
  497. {
  498.     short nnn;
  499.     
  500.     for (nnn=0;nnn<kMaxStreams;nnn++)
  501.         if (bufdata[nnn] > 0) {
  502.             short i;
  503.             
  504. /*            for (i=0;i<bufdata[nnn];i++) {
  505.                 if (buf[nnn][i] != '\f' && buf[nnn][i] != '\n')
  506.                     TEKey(buf[nnn][i], myText);
  507.             }*/
  508.             for (i=0;i<bufdata[nnn];i++) {
  509.                 if (buf[nnn][i] == '\f' || buf[nnn][i] == '\n')
  510.                     buf[nnn][i] = ' ';
  511.             }
  512.             TEInsert(buf[nnn], bufdata[nnn], myText);
  513.             CalcVBar();
  514.             
  515.             bufdata[nnn] = 0;
  516.         }
  517. }
  518.  
  519. void main()
  520. {
  521.     InitMacintosh();
  522.     GetPrefs();
  523.     SetUpMenus();
  524.     SetUpWindow();
  525.     if (NetInit()) {
  526.         stdmessage("\pError initializing MacTCP.");
  527.         Terminate();
  528.     }
  529.     ConnInit();
  530.     InitGame();
  531.  
  532. //    tprintf("PRERELEASE COPY -- DO NOT DISTRIBUTE\r\r");
  533. #if ICC
  534.     tprintf("Hi, I'm adum, and welcome to Fixation 1.3, a TCP client for the Internet Chess Club.\r");
  535.     tprintf("For more information on the Internet Chess Club check out http://www.hydra.com/icc/\r");
  536. #else
  537.     tprintf("Hi, I'm adum, and welcome to Fixation 1.3, a TCP client for the Free Internet Chess Server and ICC.\r");
  538.     tprintf("For more information on the Free Internet Chess Server check out http://chess.onenet.net/chess/\r");
  539. #endif
  540.     tprintf("Fixation is free and without warrantee.  If you want");
  541.     tprintf(" to thank me for Fixation, help my chess game (my handle is adum)!\r");
  542.     tprintf("More info + source code at http://zoo.cs.yale.edu:8000/~miller/comp/fix.html\r");
  543.     tprintf("Before reporting bugs and suggestions, please read the Bugs & Suggestions info available from the Windows menu above.\r");
  544.     tprintf("Email bugs, comments, and suggestions to miller@minerva.cis.yale.edu\r\r");
  545. //    tprintf("Local IP: "); PrintAddress(gMyAddress); tprintf("\r");
  546.     
  547. //    OpenTalker();
  548.  
  549. #if __profile__
  550.     ProfilerInit(collectDetailed, bestTimeBase, 150, 150);
  551. #endif
  552.     
  553.     do {
  554.         NetIdle();
  555.         if (!gInBackground && FrontWindow() == myWindow)
  556.             TEIdle(typeText);
  557.         ConnIdle();
  558.         ScanIncomingServer(0);
  559.         GameIdle();
  560.         HandleEvent();
  561.     } while (!timeToQuit);
  562.     
  563. #if __profile__
  564.         ProfilerDump("\patrahasis.prof");
  565.         ProfilerTerm();
  566. #endif
  567.  
  568.     ExitStuff();
  569.     Terminate();
  570. }
  571. /* end main */